package com.smedi.ismedi.authoritymanagement.core.port.adapter.restful;

import com.smedi.ismedi.authoritymanagement.api.dto.request.*;
import com.smedi.ismedi.authoritymanagement.api.dto.response.*;
import com.smedi.ismedi.authoritymanagement.api.feign.RemoteAuthorityInfrastructureFeignApi;
import com.smedi.ismedi.authoritymanagement.core.application.command.*;
import com.smedi.ismedi.authoritymanagement.core.application.query.FrameStructureQueryService;
import com.smedi.ismedi.authoritymanagement.core.application.query.TermQueryService;
import com.smedi.ismedi.authoritymanagement.core.application.query.vo.FrameStructureVo;
import com.smedi.ismedi.authoritymanagement.core.application.service.AuthorityInfrastructureApplicationService;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.TermMenu;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.TermPage;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.TermRouter;
import com.smedi.ismedi.web.starter.common.ResponseData;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @Author: xulinjun
 * @Date: 2021-7-2 20:17
 */
@Slf4j
@RestController
@AllArgsConstructor
public class AuthorityInfrastructureController implements RemoteAuthorityInfrastructureFeignApi {
    private final DozerUtil dozerUtil;

    private final AuthorityInfrastructureApplicationService authorityInfrastructureApplicationService;

    private final FrameStructureQueryService frameStructureQueryService;

    private final TermQueryService termQueryService;

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<TermMenuResponse>> postSaveTermMenu(List<TermMenuRequest> termRequests) {
        List<TermMenuCommand> commands = dozerUtil.convertor(termRequests, TermMenuCommand.class);
        List<TermMenuResponse> responses = dozerUtil.convertor(authorityInfrastructureApplicationService.batchSaveTermMenu(commands), TermMenuResponse.class);

        return new ResponseData<List<TermMenuResponse>>().success(responses);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<TermPageResponse>> postSaveTermPage(List<TermPageRequest> termRequests) {
        List<TermPageCommand> commands = dozerUtil.convertor(termRequests, TermPageCommand.class);
        List<TermPageResponse> responses = dozerUtil.convertor(authorityInfrastructureApplicationService.batchSaveTermPage(commands), TermPageResponse.class);

        return new ResponseData<List<TermPageResponse>>().success(responses);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<TermRouterResponse>> postSaveTermRouter(List<TermRouterRequest> termRequests) {
        List<TermRouterCommand> commands = dozerUtil.convertor(termRequests, TermRouterCommand.class);
        List<TermRouterResponse> responses = dozerUtil.convertor(authorityInfrastructureApplicationService.batchSaveTermRouter(commands), TermRouterResponse.class);

        return new ResponseData<List<TermRouterResponse>>().success(responses);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<TermMenuResponse> getQueryTermMenu(Long termId) {
        return new ResponseData<TermMenuResponse>().success(dozerUtil.convertor(termQueryService.getTermByTermId(termId, TermMenu.class), TermMenuResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<TermPageResponse> getQueryTermPage(Long termId) {
        return new ResponseData<TermPageResponse>().success(dozerUtil.convertor(termQueryService.getTermByTermId(termId, TermPage.class), TermPageResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<TermRouterResponse> getQueryTermRouter(Long termId) {
        return new ResponseData<TermRouterResponse>().success(dozerUtil.convertor(termQueryService.getTermByTermId(termId, TermRouter.class), TermRouterResponse.class));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<List<TermRelationshipGroupResponse>> postSaveRolePermissionType(List<TermRelationshipGroupRequest> termRelationshipGroupRequests) {
        List<TermRelationshipGroupCommand> commands = dozerUtil.convertor(termRelationshipGroupRequests, TermRelationshipGroupCommand.class);
        List<TermRelationshipGroupResponse> responses = dozerUtil.convertor(authorityInfrastructureApplicationService.batchSaveRolePermissionType(commands), TermRelationshipGroupResponse.class);

        return new ResponseData<List<TermRelationshipGroupResponse>>().success(responses);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<FrameStructureResponse> postSaveFrameStructure(FrameStructureRequest frameStructureRequest) {
        FrameStructureCommand command = dozerUtil.convertor(frameStructureRequest, FrameStructureCommand.class);
        FrameStructureResponse response = dozerUtil.mapGeneric(authorityInfrastructureApplicationService.saveFrameStructure(command), FrameStructureResponse.class);
        return new ResponseData<FrameStructureResponse>().success(response);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public ResponseData<WebClientStructureResponse> getQueryFrameStructureByRootCode(QueryFrameStructureRequest queryFrameStructureRequest) {
        String rootCode = queryFrameStructureRequest.getRootCode();
        List<String> termTypes = queryFrameStructureRequest.getTermTypes();
        Long roleId = queryFrameStructureRequest.getRoleId();

        // 获取整体框架结构
        FrameStructureVo frameStructureVo = frameStructureQueryService.queryFrameStructureByRootCode(rootCode, termTypes, roleId);
        FrameStructureResponse response = dozerUtil.mapGeneric(frameStructureVo, FrameStructureResponse.class);

        // 获取整体路由
        List<String> routers = frameStructureQueryService.queryFrameStructureRoutersByRootCode(rootCode, termTypes);

        WebClientStructureResponse webClientStructureResponse = new WebClientStructureResponse()
                .setStructureCode(frameStructureVo.getRootCode())
                .setStructureName(frameStructureVo.getRootName())
                .setStructureInfos(response.getChildren())
                .setRouters(routers);

        return new ResponseData<WebClientStructureResponse>().success(webClientStructureResponse);
    }
}
